package com.tang.campus_market.controller;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.tang.campus_market.entity.User;
import com.tang.campus_market.service.UserService;
import com.tang.campus_market.util.MailUtils;
import com.tang.campus_market.util.Result;
import com.tang.campus_market.util.StatusCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.util.Date;
import java.util.Map;
import java.util.Random;

@RestController
@CrossOrigin //跨域
@ConfigurationProperties(prefix = "disk")
public class UserController {

    @Autowired
    UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${disk}")
    private String disk;

    @RequestMapping (value = "/user/id/{id}", method = RequestMethod.GET)
    public Result getUserInfoById(@PathVariable Integer id) {
        User user = userService.selectById(id);
        user.setPassword(null);
        return new Result(StatusCode.OK,"用户信息获取成功",user);
    }
    //过滤器检测重复登录 返回提示
    @RequestMapping (value = "/user/repeatLogin", method = RequestMethod.GET)
    public Result repeatLogin(){
        return new Result(StatusCode.ERROR,"您的账号在其他地方登录");
    }
    //过滤器检测未登录 返回提示
    @RequestMapping (value = "/user/loginError", method = RequestMethod.GET)
    public Result loginError(){
        return new Result(StatusCode.ERROR,"未登录");
    }

    //由邮箱查找用户信息
    /**
     * 接收前端发过来的图片
     * @param file
     * @param httpSession
     * @return 修改结果
     * @throws Exception
     */
    @RequestMapping (value = "/user/saveProfileImage", method = RequestMethod.POST)
    public Result saveProfileImage(@RequestParam("files") MultipartFile file, HttpSession httpSession) throws Exception {
        User user = (User) httpSession.getAttribute("user");
        String fileType = file.getOriginalFilename(); //123.jpg
        fileType = fileType.substring(fileType.indexOf("."),fileType.length()); //只保留后缀名.jpg
        String uploadFileName = System.currentTimeMillis() + ".jpg";
        //判断是否图片文件
        if(!fileType.equals(".jpg") && !fileType.equals(".jpeg") && !fileType.equals(".png") )
            return new Result(StatusCode.ERROR,"请上传图片文件",null);
        if (!file.isEmpty()) {
            try {
                //创建缓存文件
                File createFile = new File(disk + ":\\" + uploadFileName + fileType);
                BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(createFile));
                out.write(file.getBytes());
                out.flush();
                out.close();
                // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1（杭州）为例，Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
                String endpoint = "https://oss-cn-shenzhen.aliyuncs.com";
                // 阿里云账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维，请登录RAM控制台创建RAM用户。
                String accessKeyId = "LTAI5tMxXRQKNBBQq6v3z9dt";
                String accessKeySecret = "agxWpWg8oZwZ1993RldLTbKpRHKM0e";
                // 创建OSSClient实例。
                OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
                // 依次填写Bucket名称（例如examplebucket）、Object完整路径（例如exampledir/exampleobject.txt）和本地文件的完整路径。Object完整路径中不能包含Bucket名称。
                PutObjectRequest putObjectRequest = new PutObjectRequest("yilutangping", "userProfileImage/" + uploadFileName, createFile);
                // 上传文件。
                ossClient.putObject(putObjectRequest);
                //上传好新头像，删除OSS上的旧头像文件
                if(!user.getPicture().equals("defaultProfileImage.jpg"))
                    ossClient.deleteObject("yilutangping", "userProfileImage/" + user.getPicture());
                // 关闭OSSClient。
                ossClient.shutdown();
                //删除缓存文件
                createFile.delete();
                //更新用户表
                user.setPicture(uploadFileName);
                userService.updateById(user);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return new Result(StatusCode.ERROR,"上传出错",null);
            } catch (IOException e) {
                e.printStackTrace();
                return new Result(StatusCode.ERROR,"上传出错",null);
            }
            return new Result(StatusCode.OK,"",user);

        } else {
            return new Result(StatusCode.ERROR,"文件为空",null);
        }
    }

    /**
     * 通过邮箱查找用户所有信息
     * @param email
     * @param session
     * @return
     */
    @RequestMapping (value = "/user/info", method = RequestMethod.POST)
    public Result UserInfo(@RequestBody String email, HttpSession session){
        User user = userService.getInfoFromEmail(email);
        return new Result(StatusCode.OK,"",user);
    }

    /**
     * 注册
     * @param user
     * @param session
     * @return
     */
    @RequestMapping(value = "/user/register",method = RequestMethod.POST)
    public Result register(@RequestBody User user, HttpSession session,HttpServletRequest request){
        if(user.getNickName().equals("") || user.getPhoneNumber().equals("") || user.getEmail().equals("") || user.getPassword().equals("")){
            return new Result(StatusCode.ERROR,"请填写完整信息",user);
        }
        Date date = new Date();
        user.setCreateDate(date);
        user.setModifyDate(date);
        User phone = userService.getInfoFromphoneNumber(user.getPhoneNumber());
        if(phone!= null){
            return new Result(StatusCode.ERROR,"该手机已被注册", null);
        }
        User email = userService.getInfoFromEmail(user.getEmail());
        if(email != null){
            return new Result(StatusCode.ERROR,"该邮箱已被注册", null);
        }
        Random rand = new Random();
        Integer activeCode = rand.nextInt(900000) + 100000 ; //6尾数激活码
        user.setCode(activeCode);

        int port = request.getServerPort();
        String ip = request.getServerName();
        String content = "点击此链接激活账号" + "http://"+ip+":"+port+"/user/activeCode?email=" + user.getEmail() +"&inputCode=" + activeCode.toString();
        MailUtils.sendMail(user.getEmail(),content,"账号激活");
        user.setIsActive("no");//账号是否激活
        user.setState("1");//0为账号停用，1为正常
        user.setPower("0");//0为用户，1为管理员
        user.setPicture("defaultProfileImage.jpg");
        if(userService.insert(user)){
            session.setAttribute("user", user);
            //2个小时*60
            session.setMaxInactiveInterval(2 * 60 * 60 * 60);
            return new Result(StatusCode.OK,"注册成功,激活链接已发送。请激活后再登录",user);
        }
        else{
            return new Result(StatusCode.ERROR,"因其他原因注册失败",user);
        }
    }

    /**
     * 激活账号
     * @param inputCode
     * @param email
     * @return
     */
    @RequestMapping (value = "/user/activeCode", method = RequestMethod.GET)
    public @ResponseBody String activeCode(@RequestParam int inputCode, String email){
        User user = userService.getInfoFromEmail(email);
        int correctCode = user.getCode();
        if(inputCode == correctCode){
            user.setIsActive("yes");
        }
        userService.updateById(user);
        return "<h1>激活成功!</h1>";
    }

    /**
     * 登录
     * @param map
     * @param session
     * @param request
     * @return
     */
    @RequestMapping (value = "/user/login", method = RequestMethod.POST)
    public Result login(@RequestBody Map<String,String> map, HttpSession session, HttpServletRequest request){
        long time1 = System.currentTimeMillis();
        System.out.println(time1);
        String inputEmail = map.get("inputEmail");
        String inputPassword = map.get("inputPassword");
        long time2 = System.currentTimeMillis();
        System.out.println(time2 - time1);
        //输入的验证码
        String tryCode = map.get("tryCode");
        //后台生成的正确的验证码
        String rightCode = (String) session.getAttribute("rightCode");
        long time3 = System.currentTimeMillis();
//        System.out.println(time3 - time2);
        User selectUser = null;
        String reallyPassword = null;

        /**************用验证码，保留这一块，下面那行注释掉******************************/
        //判断输入的验证码是否正确
        if(tryCode.equals(rightCode)) {
            selectUser = userService.getInfoFromEmail(inputEmail);
        } else{
            return new Result(StatusCode.ERROR,"验证码错误",null);
        }
        /********************************************************/

        /**************不用验证码的话注释掉上面，保留这行******************************/
//        selectUser = userService.getInfoFromEmail(inputEmail);
        /********************************************************/
        //判断用户是否存在
        long time4 = System.currentTimeMillis();
        System.out.println(time4 - time3);
        if(selectUser != null) {
            reallyPassword = selectUser.getPassword();
        } else{
            return new Result(StatusCode.LOGINERROR,"用户不存在",null);
        }

        if(!selectUser.getIsActive().equals("yes")){
            return new Result(StatusCode.ERROR,"请激活账号后再登录",selectUser);
        }
        //判断密码是否正确
        if(inputPassword.equals(reallyPassword)){
            session.setAttribute("user", selectUser);
            redisTemplate.opsForValue().set(selectUser.getEmail(),session.getId());
            //2个小时*60
            session.setMaxInactiveInterval(2 * 60 * 60 * 60);
            return new Result(StatusCode.OK,"登录成功",selectUser);
        } else{
            return new Result(StatusCode.LOGINERROR,"密码错误",null);
        }
    }

    /**
     * 退出当前账号
     * @param session
     * @return
     */
    @RequestMapping (value = "/user/logout", method = RequestMethod.GET)
    public @ResponseBody Result logout(HttpSession session){
        session.removeAttribute("user");
        return new Result(StatusCode.OK,"",null);
    }

    /**
     * 修改个人信息
     * @param map
     * @param session
     * @return
     */
    @RequestMapping(value = "/user/updateInfo",method = RequestMethod.POST)
    public Result updateInfo(@RequestBody Map<String, String> map, HttpSession session){
        //原信息的邮箱，特意获取一个修改之前的邮箱，是为了防止获取到修改后的邮箱导致找不到user的信息
        String oldEmail = map.get("oldEmail");

        User user = userService.getInfoFromEmail(oldEmail);
        int userid = user.getId();
        User phoneUser = userService.getInfoFromphoneNumber(map.get("mobile"));
        if(phoneUser != null && Integer.parseInt(String.valueOf(phoneUser.getId())) != userid){
            return new Result(StatusCode.ERROR,"该手机已被注册", null);
        }
        User emailUser = userService.getInfoFromEmail(map.get("email"));

        if(emailUser != null && Integer.parseInt(String.valueOf(emailUser.getId())) != userid){
            return new Result(StatusCode.ERROR,"该邮箱已被注册", null);
        }
        User nameUser = userService.getInfoFromName(map.get("name"));
        if(nameUser != null && Integer.parseInt(String.valueOf(nameUser.getId())) != userid){
            return new Result(StatusCode.ERROR,"该昵称已被注册", null);
        }
        user.setNickName(map.get("name"));
        user.setSex(map.get("gender"));
        user.setPhoneNumber(map.get("mobile"));
        user.setEmail(map.get("email"));
        user.setModifyDate(new Date());
        if(userService.updateById(user)){
            session.setAttribute("user", user);
            //2个小时*60
            session.setMaxInactiveInterval(2 * 60 * 60 * 60);
            return new Result(StatusCode.OK,"修改成功，请重新登录！",user);
        }
        else{
            return new Result(StatusCode.ERROR,"修改失败，请重试",user);
        }
    }

    /**
     * 修改密码
     * @param map
     * @param session
     * @return
     */
    @RequestMapping (value = "/user/updatePassword", method = RequestMethod.POST)
    public Result updatePassword(@RequestBody Map<String, String> map, HttpSession session){
        User user = userService.getInfoFromEmail(map.get("email"));
        user.setPassword(map.get("newPassword"));
        userService.updateById(user);
        return new Result(StatusCode.OK,"密码修改成功，请重新登录！",user);
    }

    /**
     * 从session获取用户信息
     * @param inputCode
     * @param session
     * @return
     */
    @RequestMapping (value = "/user/preInfo", method = RequestMethod.POST)
    public Result preInfo(@RequestBody Integer inputCode, HttpSession session){
        User user = (User) session.getAttribute("user");
        return new Result(StatusCode.OK,"获取成功",user);
    }

    /**
     * 查看注册手机号码是否重复
     * @param map
     * @return
     */
    @RequestMapping (value = "/user/checkPhone", method = RequestMethod.POST)
    public Result checkPhone(@RequestBody Map<String, String> map){
        String oldemail = map.get("oldEmail");
        //获取不到oldemail说明是注册页
        if(oldemail == null){
            String phoneNum = map.get("phoneNum");
            //通过手机号码查询用户
            User user = userService.getInfoFromphoneNumber(phoneNum);
            //查询不到说明该手机号还没人注册
            if(user == null ){
                return new Result(StatusCode.OK,"", null);
            }
            else{
                return new Result(StatusCode.ERROR,"该手机号码已被注册", null);
            }
        }
        //获取得到oldemail说明是修改个人信息页
        else{
            String phoneNum = map.get("phoneNum");
            User user = userService.getInfoFromphoneNumber(phoneNum);
            User oldUser = userService.getInfoFromEmail(oldemail);
            //判断查出的用户是否是用户自己
            if(user.getId().equals(oldUser.getId())){
                return new Result(StatusCode.OK,"", null);
            }
            else{
                return new Result(StatusCode.ERROR,"该手机号码已被注册", null);
            }
        }
    }

    /**
     * 查看注册邮箱是否重复
     * @param map
     * @return
     */
    @RequestMapping (value = "/user/checkEmail", method = RequestMethod.POST)
    public Result checkEmail(@RequestBody Map<String, String> map){
        String oldemail = map.get("oldEmail");
        //获取不到oldemail说明是注册页
        if(oldemail == null){
            String email = map.get("email");
            //通过邮箱查询用户
            User user = userService.getInfoFromEmail(email);
            //查询不到说明该邮箱还没人注册
            if(user == null ){
                return new Result(StatusCode.OK,"", null);
            }
            else{
                return new Result(StatusCode.ERROR,"该邮箱已被注册", null);
            }
        }
        //获取得到oldemail说明是修改个人信息页
        else{
            String email = map.get("email");
            User user = userService.getInfoFromEmail(email);
            User oldUser = userService.getInfoFromEmail(oldemail);
            //判断查出的用户是否是用户自己
            if(user.getId().equals(oldUser.getId())){
                return new Result(StatusCode.OK,"", null);
            }
            else{
                return new Result(StatusCode.ERROR,"该邮箱已被注册", null);
            }
        }
    }

    /**
     * 查看昵称是否重复
     * @param map
     * @return
     */
    @RequestMapping (value = "/user/checkName", method = RequestMethod.POST)
    public Result checkName(@RequestBody Map<String, String> map){
        String oldemail = map.get("oldEmail");
        //获取不到oldemail说明是注册页
        if(oldemail == null){
            String name = map.get("name");
            //通过用户名查询用户
            User user = userService.getInfoFromName(name);
            //查询不到说明该昵称还没人注册
            if(user == null ){
                return new Result(StatusCode.OK,"", null);
            }
            else{
                return new Result(StatusCode.ERROR,"该昵称已被注册", null);
            }
        }
        //获取到oldemail说明是修改个人信息页
        else{
            String name = map.get("name");
            User user = userService.getInfoFromName(name);
            User oldUser = userService.getInfoFromEmail(oldemail);
            //判断查出的用户是否是用户自己
            if(user.getId().equals(oldUser.getId())){
                return new Result(StatusCode.OK,"", null);
            }
            else{
                return new Result(StatusCode.ERROR,"该昵称已被注册", null);
            }
        }
    }
}
